'''
函数代码块以 def 关键词开头，后接函数标识符名称和圆括号 ()。
任何传入参数和自变量必须放在圆括号中间，圆括号之间可以用于定义参数。
函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
函数内容以冒号起始，并且缩进。
return [表达式] 结束函数，选择性地返回一个值给调用方。不带表达式的return相当于返回 None。
'''

#一个基本的函数
'''
def hello() :
    print("Hello World!")
hello()
'''

#带参数,返回值的函数
'''
def area(width, height):
    return width * height
num = area(10,5)
print (num)
'''

#python 传不可变对象实例
'''
def ChangeInt( a ):
    a = 10
    print(a)# 结果是 10

b = 2
ChangeInt(b)
print( b ) # 结果是 2
'''

#传可变对象实例,在内部修改传入的值，而不是赋值
'''
def changeme( mylist ):
   "修改传入的列表"
   mylist.append([1,2,3,4])#这里是修改值，是指针的引用。而不是赋值语句
   print ("函数内取值: ", mylist)# [10, 20, 30, [1, 2, 3, 4]]
   return

# 调用changeme函数
mylist = [10,20,30]
changeme( mylist )
print ("函数外取值: ", mylist)# [10, 20, 30, [1, 2, 3, 4]]  
'''

#参数

#必需参数，不传会报错
'''
def printme( str ):
   print (str)
   return
 
#调用printme函数
printme(123)
'''

#关键字参数,给指定参数赋值
'''
def printinfo( name, age ):
   "打印任何传入的字符串"
   print ("名字: ", name)
   print ("年龄: ", age)
   return
 
#调用printinfo函数
printinfo( age=50, name="runoob" )
'''

#函数设置默认值
'''
def printinfo( name, age = 35 ):
   "打印任何传入的字符串"
   print ("名字: ", name)
   print ("年龄: ", age)
   return
 
#调用printinfo函数
printinfo( age=50, name="runoob" )
printinfo( name="runoob" )#默认值参数可以不填
'''

#不定长参数, *vartuple：除了对应参数以外的参数
'''
def printinfo( arg1, *vartuple ):
   print ("arg1: ", arg1)
   print ("*vartuple: ", vartuple)
   for var in vartuple:
      print (var)
   return
printinfo( 10 )
printinfo( 70, 60, 50 )
'''

#匿名函数,使用lambda修饰的参数为匿名函数，不过返回值用一个变量接收，也相当于有函数名
'''
sum = lambda arg1, arg2: arg1 + arg2
print ("相加后的值为 : ", sum( 10, 20 ))
print ("相加后的值为 : ", sum( 50, 20 ))
'''

#return 语句，默认返回None
'''
def sum( arg1, arg2 ):
   # 返回2个参数的和."
   total = arg1 + arg2
   return total

# 调用sum函数
total = sum( 10, 20 )
print ("函数返回 : ", total)
'''

#变量作用域,分为以下作用域
#L （Local） 局部作用域
#E （Enclosing） 闭包函数外的函数中
#G （Global） 全局作用域
#B （Built-in） 内建作用域
'''
x = int(2.9)  # 内建作用域
g_count = 0  # 全局作用域
def outer():
    o_count = 1  # 闭包函数外的函数中
    def inner():
        i_count = 2  # 局部作用域
'''

#全局变量和局部变量
'''
定义在函数内部的变量拥有一个局部作用域，定义在函数外的拥有全局作用域。
局部变量只能在其被声明的函数内部访问，而全局变量可以在整个程序范围内访问。
调用函数时，所有在函数内声明的变量名称都将被加入到作用域中。
'''
'''
total = 0 # 这是一个全局变量
# 可写函数说明
def sum( arg1, arg2 ):
    #返回2个参数的和."
    total = arg1 + arg2 # total在这里是局部变量.
    print ("函数内是局部变量 : ", total)#30
    return total

#调用sum函数
sum( 10, 20 )
print ("函数外是全局变量 : ", total)#10
'''


#global 和 nonlocal关键字
'''
需求：当内部作用域想修改外部作用域的变量时，就要用到global和nonlocal关键字了
'''
'''
num = 1
def fun1():
    global num  # 需要使用 global 关键字声明,把全局作用域引用到函数内部使用
    print(num)  # 1
    num = 123
    print(num)  #123
    return
fun1()

print(num)      #123
'''


#修改嵌套作用域中的变量则需要 nonlocal 关键字
'''
num = 1                # 全局作用域
def outer():
    num = 10           # 嵌套作用域
    def inner():
        nonlocal num   # nonlocal关键字声明,把嵌套作用域修改为当前函数作用域
        num = 100
        print(num)     # 100
    inner()
    print(num)         # 100
    return
outer()
print(num)             # 1
'''


#以下程序会报错
'''
a = 10
def test():
    global a        #不加这一段会报错，因为是给全局变量赋值，要想赋值就必须使用global关键字在函数局部作用域内修饰全局变量，不然报错
    a = a + 1
    print(a)
test()
'''